/*
 * Created by SharpDevelop.
 * User: fatman
 * Date: 10/27/2008
 * Time: 3:02 AM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Collections;


namespace CUALib
{
	/// <summary>
	/// Description of ConsoleControl.
	/// </summary>
	public abstract class ConsoleControl : Component
	{
		
		
		public ConsoleControl(bool consoleExists)
		{
			
			_controls = new ConsoleControlCollection(this);

			this._decorationSet = new BoxDrawingDecorationSet();
			this._colorSet = new BoxDrawingColorSet();

			this._foregroundColor = _colorSet [BoxDrawingColorNames.foreground];
			this._backgroundColor = _colorSet [BoxDrawingColorNames.background];

			this.ConsoleExists = consoleExists;
		}

		public abstract void Invalidate(Rectangle rect);

		public virtual void Invalidate()
		{
			if (!Visible)
				return;
			Invalidate(AbsoluteBounds);
		}
		
		public virtual void Invalidate(Rectangle rect, bool invalidateChildren)
		{
			if (!Visible)
				return;
			Invalidate(rect);
			if (invalidateChildren)
			{
				foreach (ConsoleControl c in Controls)
				{
					c.Invalidate(rect, invalidateChildren);
				}
			}

		}

		public virtual void Invalidate(bool invalidateChildren)
		{
			if (!Visible)
				return;
			Invalidate(AbsoluteBounds, invalidateChildren);
		}

		private BoxDrawingDecorationSet _decorationSet=null;

		public virtual BoxDrawingDecorationSet DecorationSet
		{
			get
			{
				return _decorationSet;
			}
			set
			{
				_decorationSet = value;
				if(this.TopLevelParent==this) //Window that is
				{
					OverrideDecorationSet(value);
				}
				
				
			}
		}

		public virtual void OverrideDecorationSet(BoxDrawingDecorationSet newDecorationSet)
		{
			
			foreach(ConsoleControl cc in Controls)
			{
				cc.OverrideDecorationSet(newDecorationSet);
				cc.DecorationSet=newDecorationSet;
			}
			
		}
		
		
		private BoxDrawingColorSet _colorSet;

		public BoxDrawingColorSet ColorSet
		{
			get { return _colorSet; }
			set { _colorSet = value; }
		}
		
		private System.Drawing.Point _location = System.Drawing.Point.Empty;

		public virtual System.Drawing.Point Location
		{
			get
			{
				return _location;
			}
			set
			{
				_location = value;


			}
		}

		private System.Drawing.Size _size = System.Drawing.Size.Empty;

		public virtual System.Drawing.Size Size
		{
			get
			{
				return _size;
			}
			set
			{
				_size = value;


			}
		}

		private ConsoleControlCollection _controls;

		public ConsoleControlCollection Controls
		{
			get
			{
				return _controls;
			}
		}

		private ConsoleControl _parent = null;

		public virtual ConsoleControl Parent
		{
			get { return _parent; }
			set
			{
				_parent = value;
			}
		}
		
		public Rectangle AbsoluteBounds
		{
			get
			{
				Rectangle ret = new Rectangle(Location, Size);

				if (Parent != null)
				{
					Point p = Location;
					p.Offset(Parent.AbsoluteBounds.Location);
					ret.Location = p;
				}

				return ret;
			}
		}

		private bool _consoleExists = true;
		
		public bool ConsoleExists
		{
			get { return _consoleExists; }
			set { _consoleExists = value; }
		}

		private ConsoleColor _backgroundColor = ConsoleColor.DarkGray;

		public ConsoleColor BackgroundColor
		{
			get
			{
				return _backgroundColor;
			}
			set
			{
				_backgroundColor = value;
				Redraw();
			}
		}

		private ConsoleColor _foregroundColor = ConsoleColor.White;

		public ConsoleColor ForegroundColor
		{
			get
			{
				return _foregroundColor;
			}
			set
			{
				_foregroundColor = value;
				Redraw();
			}
		}

		internal virtual void Redraw() { }

		private bool _focused;
		public virtual bool Focused
		{
			get { return _focused; }
			set
			{
				_focused = value;
				if (Focused)
				{
					ForegroundColor = this.ColorSet [BoxDrawingColorNames.focusForeground];
					BackgroundColor = this.ColorSet [BoxDrawingColorNames.focusBackground];
				}
				else
				{
					ForegroundColor = this.ColorSet [BoxDrawingColorNames.foreground];
					BackgroundColor = this.ColorSet [BoxDrawingColorNames.background];
				}
				Redraw();

			}
		}

		public virtual void Focus()
		{
			Focused = true;
			if (TopLevelParent != null)
			{
				TopLevelParent.ActiveControl = this;
			}
			Redraw();
		}
		
		public bool HasChildren
		{
			get { return Controls.Count > 0; }
		}

		/*
		public virtual ConsoleControl xFindNextControl()
		{
			if (HasChildren)
			{
				
				return Controls [0];
			}
			else
			{
				
				if (Parent != null)
				{
					int thisIdx = Parent.Controls.IndexOf(this);
					if (Parent.Controls.Count > thisIdx + 1)
					{
						return Parent.Controls [thisIdx + 1];
					}
					else
					{
						return Parent.FindNextControl();
					}
				}
			}
			return null;
		}

		 */

		public virtual ConsoleControl FindNextControl()
		{
			return FindNextControl(this);
		}
		private ConsoleControl FindNextControl(ConsoleControl callerControl)
		{
			if (HasChildren && callerControl.Parent != this)
			{
				/*get first child*/
				return Controls [0];
			}
			else
			{
				/*get next brother*/
				if (Parent != null)
				{
					int thisIdx = Parent.Controls.IndexOf(this);
					if (Parent.Controls.Count > thisIdx + 1)
					{
						return Parent.Controls [thisIdx + 1];
					}
					else
					{
						return Parent.FindNextControl(this);
					}
				}
			}
			return this;
		}

		public virtual ConsoleControl TopLevelParent
		{
			get
			{
				if (_parent != null)
				{
					//Console.WriteLine("PARENT NOT NULL {0} {1}",GetType().Name, _name);
					return _parent.TopLevelParent;
				}
				return null;
			}
		}
		
		private ConsoleControl _activeControl;

		public virtual ConsoleControl ActiveControl
		{
			get { return _activeControl; }
			set
			{

				if (_activeControl != null)
					_activeControl.Invalidate(true);
				_activeControl = value;
			}
		}
		
		private string _name = String.Empty;
		public string Name
		{
			get { return _name; }
			set { _name = value; }
		}

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder(this.GetType().FullName);
			sb.Append(" Name:");
			sb.Append(this.Name);
			return sb.ToString();

		}
		
		public virtual bool ReceiveEvent(ConsoleKeyInfo cki)
		{
			return Focused;
		}
		public void ReceiveEvent(ConsoleKeyInfo cki, bool sendToChildren)
		{
			ReceiveEvent(cki);
			foreach (ConsoleControl cc in Controls)
			{
				cc.ReceiveEvent(cki, sendToChildren);
			}

		}

		public virtual int Width
		{
			get { return Size.Width; }
			set
			{
				if(value!=Size.Width)
				{
					Size=new Size(value,Size.Height);
					Invalidate(true);
				}
			}
		}

		public virtual int Height
		{
			get { return Size.Height; }
			set
			{
				if(value!=Size.Height)
				{
					Size=new Size(Size.Width,value);
					Invalidate(true);
				}
			}
		}
		
		public virtual int Left
		{
			get { return Location.X; }
			set
			{
				if(value!=Location.X)
				{
					Location=new Point(value,Location.Y);
					Invalidate(true);
				}
			}
		}
		public virtual int Top
		{
			get { return Location.Y; }
			set
			{
				if(value!=Location.Y)
				{
					Location=new Point(Location.X,value);
					Invalidate(true);
				}
			}
		}
		
		

		public virtual Rectangle ContentRect
		{
			get { return Rectangle.Empty; }
		}
		
		
		private bool _visible=true;
		public virtual bool Visible
		{
			get {return _visible;}
			set {
				
				if(value && !_visible)
				{
					_visible=value;
					Invalidate(true);
				}
				else
				{
					_visible=value;
				}
				
				
			}
			
		}
		
		public virtual void ControlAdded(ConsoleControl item, int index)
		{
			
		}
		public virtual void ControlRemoved(ConsoleControl item, int index)
		{
			
		}
		

	}

}
